User-level semaphores are provided by IRIX and accessible to programmers via the shared arena facility [17]. A shared arena allows related or unrelated processes to allocate and share semaphores [5], locks, and memory. SGI's X server multi-rendering facility uses the shared arena's semaphore mechanism. The semaphores are termed user-level because only when a process must block on a semaphore does the process need to enter the kernel. In the common case of no contention on the semaphore, the semaphore can be acquired (P) and released (V) with no kernel intervention. This means user-level semaphores are considerably more efficient than a semaphore mechanism that requires a system call per semaphore access.
A variation on user-level semaphores (requiring more kernel support than simple user-level semaphores) is the pollable semaphore. When an acquire operation is attempted by a process and the semaphore is not immediately available, instead of blocking, the process is queued to receive the semaphore and the process continues to execute. A pollable semaphore has an accompanying file descriptor. This file descriptor can be specified in the select system call read mask. When the semaphore is acquirable, the next select call on the accompanying file descriptor will fall through with the semaphore acquired by the selecting process.
In the case of multi-rendering, a pollable semaphore is used to coordinate request completion with the X server's main thread. The X server can select on the pollable semaphore's accompanying file descriptor just like the file descriptors for client and device input.
The user-level and pollable semaphores are designed to be used with process share groups. In conjunction, true multi-processor concurrency with minimal synchronization overhead can be achieved. The pollable semaphores are particularly well suited for a program like the X server which multiplexes several input sources and sinks via the select system call.